// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.ai.states;

import java.util.HashMap;
import zombie.ai.State;
import zombie.audio.parameters.ParameterZombieState;
import zombie.characters.IsoGameCharacter;
import zombie.characters.IsoPlayer;
import zombie.characters.IsoZombie;
import zombie.characters.skills.PerkFactory;
import zombie.core.Rand;
import zombie.core.skinnedmodel.advancedanimation.AnimEvent;
import zombie.iso.LosUtil;
import zombie.iso.Vector2;
import zombie.network.GameClient;
import zombie.network.GameServer;
import zombie.util.StringUtils;

public final class AttackState extends State {
    private static final AttackState s_instance = new AttackState();
    private static final String frontStr = "FRONT";
    private static final String backStr = "BEHIND";
    private static final String rightStr = "LEFT";
    private static final String leftStr = "RIGHT";

    public static AttackState instance() {
        return s_instance;
    }

    @Override
    public void enter(IsoGameCharacter owner) {
        IsoZombie isoZombie = (IsoZombie)owner;
        HashMap hashMap = owner.getStateMachineParams(this);
        hashMap.clear();
        hashMap.put(0, Boolean.FALSE);
        owner.setVariable("AttackOutcome", "start");
        owner.clearVariable("AttackDidDamage");
        owner.clearVariable("ZombieBiteDone");
    }

    @Override
    public void execute(IsoGameCharacter owner) {
        HashMap hashMap = owner.getStateMachineParams(this);
        IsoZombie isoZombie = (IsoZombie)owner;
        IsoGameCharacter isoGameCharacter0 = (IsoGameCharacter)isoZombie.target;
        if (isoGameCharacter0 == null || !"Chainsaw".equals(isoGameCharacter0.getVariableString("ZombieHitReaction"))) {
            String string = owner.getVariableString("AttackOutcome");
            if ("success".equals(string) && owner.getVariableBoolean("bAttack") && owner.isVariable("targethitreaction", "EndDeath")) {
                string = "enddeath";
                owner.setVariable("AttackOutcome", string);
            }

            if ("success".equals(string)
                && !owner.getVariableBoolean("bAttack")
                && !owner.getVariableBoolean("AttackDidDamage")
                && owner.getVariableString("ZombieBiteDone") == null) {
                owner.setVariable("AttackOutcome", "interrupted");
            }

            if (isoGameCharacter0 == null || isoGameCharacter0.isDead()) {
                isoZombie.setTargetSeenTime(10.0F);
            }

            if (isoGameCharacter0 != null
                && hashMap.get(0) == Boolean.FALSE
                && !"started".equals(string)
                && !StringUtils.isNullOrEmpty(owner.getVariableString("PlayerHitReaction"))) {
                hashMap.put(0, Boolean.TRUE);
                isoGameCharacter0.testDefense(isoZombie);
            }

            isoZombie.setShootable(true);
            if (isoZombie.target != null && !isoZombie.bCrawling) {
                if (!"fail".equals(string) && !"interrupted".equals(string)) {
                    isoZombie.faceThisObject(isoZombie.target);
                }

                isoZombie.setOnFloor(false);
            }

            boolean _boolean = isoZombie.speedType == 1;
            if (isoZombie.target != null && _boolean && ("start".equals(string) || "success".equals(string))) {
                IsoGameCharacter isoGameCharacter1 = (IsoGameCharacter)isoZombie.target;
                float _float = isoGameCharacter1.getSlowFactor();
                if (isoGameCharacter1.getSlowFactor() <= 0.0F) {
                    isoGameCharacter1.setSlowTimer(30.0F);
                }

                isoGameCharacter1.setSlowTimer(isoGameCharacter1.getSlowTimer() + zombie.GameTime.instance.getMultiplier());
                if (isoGameCharacter1.getSlowTimer() > 60.0F) {
                    isoGameCharacter1.setSlowTimer(60.0F);
                }

                isoGameCharacter1.setSlowFactor(isoGameCharacter1.getSlowFactor() + 0.03F);
                if (isoGameCharacter1.getSlowFactor() >= 0.5F) {
                    isoGameCharacter1.setSlowFactor(0.5F);
                }

                if (GameServer.bServer && _float != isoGameCharacter1.getSlowFactor()) {
                    GameServer.sendSlowFactor(isoGameCharacter1);
                }
            }

            if (isoZombie.target != null) {
                isoZombie.target.setTimeSinceZombieAttack(0);
                isoZombie.target.setLastTargettedBy(isoZombie);
            }

            if (!isoZombie.bCrawling) {
                isoZombie.setVariable("AttackType", "bite");
            }
        }
    }

    @Override
    public void exit(IsoGameCharacter owner) {
        IsoZombie isoZombie = (IsoZombie)owner;
        owner.clearVariable("AttackOutcome");
        owner.clearVariable("AttackType");
        owner.clearVariable("PlayerHitReaction");
        owner.setStateMachineLocked(false);
        if (isoZombie.target != null && isoZombie.target.isOnFloor()) {
            isoZombie.setEatBodyTarget(isoZombie.target, true);
            isoZombie.setTarget(null);
        }

        isoZombie.AllowRepathDelay = 0.0F;
    }

    @Override
    public void animEvent(IsoGameCharacter owner, AnimEvent event) {
        IsoZombie isoZombie = (IsoZombie)owner;
        if (event.m_EventName.equalsIgnoreCase("SetAttackOutcome")) {
            if (isoZombie.getVariableBoolean("bAttack")) {
                isoZombie.setVariable("AttackOutcome", "success");
            } else {
                isoZombie.setVariable("AttackOutcome", "fail");
            }
        }

        if (event.m_EventName.equalsIgnoreCase("AttackCollisionCheck") && !isoZombie.isNoTeeth()) {
            IsoGameCharacter isoGameCharacter = (IsoGameCharacter)isoZombie.target;
            if (isoGameCharacter == null) {
                return;
            }

            isoGameCharacter.setHitFromBehind(isoZombie.isBehind(isoGameCharacter));
            String string = isoGameCharacter.testDotSide(isoZombie);
            boolean _boolean = string.equals("FRONT");
            if (_boolean && !isoGameCharacter.isAimAtFloor() && !StringUtils.isNullOrEmpty(isoGameCharacter.getVariableString("AttackType"))) {
                return;
            }

            if ("KnifeDeath".equals(isoGameCharacter.getVariableString("ZombieHitReaction"))) {
                int int0 = isoGameCharacter.getPerkLevel(PerkFactory.Perks.SmallBlade) + 1;
                int int1 = Math.max(0, 9 - int0 * 2);
                if (Rand.NextBool(int1)) {
                    return;
                }
            }

            this.triggerPlayerReaction(owner.getVariableString("PlayerHitReaction"), owner);
            Vector2 vector2 = isoZombie.getHitDir();
            vector2.x = isoZombie.getX();
            vector2.y = isoZombie.getY();
            vector2.x = vector2.x - isoGameCharacter.getX();
            vector2.y = vector2.y - isoGameCharacter.getY();
            vector2.normalize();
            if (GameClient.bClient && !isoZombie.isRemoteZombie()) {
                GameClient.sendHitCharacter(isoZombie, isoGameCharacter, null, 0.0F, false, 1.0F, false, false, false);
            }
        }

        if (event.m_EventName.equalsIgnoreCase("EatBody")) {
            owner.setVariable("EatingStarted", true);
            ((IsoZombie)owner).setEatBodyTarget(((IsoZombie)owner).target, true);
            ((IsoZombie)owner).setTarget(null);
        }

        if (event.m_EventName.equalsIgnoreCase("SetState")) {
            isoZombie.parameterZombieState.setState(ParameterZombieState.State.Attack);
        }
    }

    @Override
    public boolean isAttacking(IsoGameCharacter owner) {
        return true;
    }

    private void triggerPlayerReaction(String string1, IsoGameCharacter isoGameCharacter0) {
        IsoZombie isoZombie = (IsoZombie)isoGameCharacter0;
        IsoGameCharacter isoGameCharacter1 = (IsoGameCharacter)isoZombie.target;
        if (isoGameCharacter1 != null) {
            if (!(isoZombie.DistTo(isoGameCharacter1) > 1.0F) || isoZombie.bCrawling) {
                if (!isoZombie.isFakeDead() && !isoZombie.bCrawling || !(isoZombie.DistTo(isoGameCharacter1) > 1.3F)) {
                    if ((!isoGameCharacter1.isDead() || isoGameCharacter1.getHitReaction().equals("EndDeath")) && !isoGameCharacter1.isOnFloor()) {
                        if (!isoGameCharacter1.isDead()) {
                            isoGameCharacter1.setHitFromBehind(isoZombie.isBehind(isoGameCharacter1));
                            String string0 = isoGameCharacter1.testDotSide(isoZombie);
                            boolean boolean0 = string0.equals("FRONT");
                            boolean boolean1 = string0.equals("BEHIND");
                            if (string0.equals("RIGHT")) {
                                string1 = string1 + "LEFT";
                            }

                            if (string0.equals("LEFT")) {
                                string1 = string1 + "RIGHT";
                            }

                            if (!((IsoPlayer)isoGameCharacter1).bDoShove || !boolean0 || isoGameCharacter1.isAimAtFloor()) {
                                if (!((IsoPlayer)isoGameCharacter1).bDoShove || boolean0 || boolean1 || Rand.Next(100) <= 75) {
                                    if (!(Math.abs(isoZombie.z - isoGameCharacter1.z) >= 0.2F)) {
                                        LosUtil.TestResults testResults = LosUtil.lineClear(
                                            isoZombie.getCell(),
                                            (int)isoZombie.getX(),
                                            (int)isoZombie.getY(),
                                            (int)isoZombie.getZ(),
                                            (int)isoGameCharacter1.getX(),
                                            (int)isoGameCharacter1.getY(),
                                            (int)isoGameCharacter1.getZ(),
                                            false
                                        );
                                        if (testResults != LosUtil.TestResults.Blocked && testResults != LosUtil.TestResults.ClearThroughClosedDoor) {
                                            if (!isoGameCharacter1.getSquare().isSomethingTo(isoZombie.getCurrentSquare())) {
                                                isoGameCharacter1.setAttackedBy(isoZombie);
                                                boolean boolean2 = false;
                                                if (!GameClient.bClient && !GameServer.bServer || GameClient.bClient && !isoZombie.isRemoteZombie()) {
                                                    boolean2 = isoGameCharacter1.getBodyDamage().AddRandomDamageFromZombie(isoZombie, string1);
                                                }

                                                isoGameCharacter0.setVariable("AttackDidDamage", boolean2);
                                                isoGameCharacter1.getBodyDamage().Update();
                                                if (isoGameCharacter1.isDead()) {
                                                    isoGameCharacter1.setHealth(0.0F);
                                                    isoZombie.setEatBodyTarget(isoGameCharacter1, true);
                                                    isoZombie.setTarget(null);
                                                } else if (isoGameCharacter1.isAsleep()) {
                                                    if (GameServer.bServer) {
                                                        isoGameCharacter1.sendObjectChange("wakeUp");
                                                    } else {
                                                        isoGameCharacter1.forceAwake();
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    } else {
                        isoZombie.setEatBodyTarget(isoGameCharacter1, true);
                    }
                }
            }
        }
    }
}
